﻿using System;
using System.Security.Principal;
using DomainModel;
using Repository.Abstract;
using Services.Abstract;

namespace Services.Concrete
{
    public class GroupService : Service<Group>, IGroupService
    {
        private readonly IGroupRepository _groupRepository;

        public GroupService(IGroupRepository groupRepository, IPrincipal currentUser,
                            IPermissionService permissionService)
            : base(groupRepository, currentUser, permissionService)
        {
            _groupRepository = groupRepository;
        }

        public void SetPraepostor(Group group, User student)
        {
            if (student.Role != Role.Student)
                throw new Exception("Пользователь - не студент. Его нельзя сделать старостой.");

            if (!PermissionService.CanChangePraepostor(group))
                throw new Exception("Недостаточно прав чтобы менять старосту группы.");

            group.Praepostor = student;
            SaveOrUpdateNoPermissionsCheck(group);
        }

        public Group TeacherIsCurator(User teacher)
        {
            if (teacher == null)
                throw new ArgumentNullException("teacher");

            if (teacher.Role != Role.Teacher)
                throw new Exception("Преподаватель не преподаватель.");

            return _groupRepository.TeacherIsCurator(teacher);
        }

        public Group StudentIsPraepostor(User student)
        {
            if (student == null)
                throw new ArgumentNullException("student");

            if (student.Role != Role.Student)
                throw new Exception("Студент не студент.");

            return _groupRepository.StudentIsPraepostor(student);
        }

        public void SaveOrUpdateNoPermissionsCheck(Group group)
        {
            if (group == null)
                throw new ArgumentNullException("group");

            if (string.IsNullOrEmpty(group.Name))
                throw new Exception("Необходимо ввести название.");

            if (group.Curator != null && @group.Curator.Role != Role.Teacher)
                throw new Exception("Куратором может быть только преподаватель.");

            if (group.Praepostor != null)
            {
                if (group.Praepostor.Role != Role.Student)
                    throw new Exception("Старостой может быть только студент.");

                if (group.Praepostor.Group.Id != group.Id)
                    throw new Exception("Старостой не может быть студент другой группы.");
            }

            base.SaveOrUpdate(group);
        }

        public new void SaveOrUpdate(Group group)
        {
            if (!PermissionService.CanCUDGroups())
                throw new Exception("Недостаточно прав чтобы делать CUD операции с группами.");

            SaveOrUpdateNoPermissionsCheck(group);
        }
    }
}